package cn.zhx.singleton.demo;

/**
 * 懒汉式 线程安全 双重检查锁
 * 类加载不会导致该单实例对象被创建，而是首次使用该对象时才会创建
 */
public class Singleton03 {
    private Singleton03(){}

    //在多线程的情况下，可能会出现空指针问题，出现问题的原因是JVM在实例化对象的时候会进行优化和指令重排序操作。
    //使用volatile关键字可以禁用指令重排序进而保证有序性。
    private static volatile Singleton03 instance;

    /**
     * 对于 `getInstance()` 方法来说，绝大部分的操作都是读操作，读操作是线程安全的，
     * 所以我们没必让每个线程必须持有锁才能调用该方法，我们需要调整加锁的时机。由此也产生了一种新的实现模式：双重检查锁模式
     * @return
     */
    public static Singleton03 getInstance(){
        if(instance == null){
            synchronized (Singleton03.class){
                if(instance == null){
                    instance = new Singleton03();
                }
            }
        }
        return instance;
    }
}
